#include<yaml-cpp/yaml.h>
#include<iostream>
#include<string>
#include<vector>
#include<set>


#include"qtch/qtch.h"


static qtch::Logger::ptr logger = QTCH_LOG_ROOT();
void test_yaml(){
    YAML::Node config;
    try{
        config = YAML::LoadFile("./bin/conf/log.yml");
    }catch(YAML::BadFile &e){
        std::cout<<"read file error"<<std::endl;
        return;
    }
    std::cout << "config.size:" << config["logs"][0]["name"].size() << std::endl;
    std::cout << "Node type " << config["logs"].Type() << std::endl;
    std::cout << "config[logs]:" <<std::endl<< config["logs"] << std::endl;
    std::cout << std::endl;
    for(size_t i=0;i<config["logs"].size(); ++i){
        std::cout << config["logs"][i]["name"].as<std::string>() << std::endl;
    }
}

void test_config(){
    qtch::ConfigVar<int>::ptr test_int = qtch::Config::LookUp("server.port",8080,"server port");
    QTCH_LOG_INFO(logger)<<"test int "<<test_int->getValue();
    uint64_t key=test_int->addListener([test_int](const int& old_value,const int& new_value){
        QTCH_LOG_INFO(logger)<<test_int->getName()<<" change value from "<<old_value<<" to "<<new_value;
    });
    test_int->setValue(1000);
    QTCH_LOG_INFO(logger)<<"test int "<<test_int->getValue();
    test_int->setValue(1000);
    test_int->delListener(key);
    test_int->setValue(2000);
    QTCH_LOG_INFO(logger)<<"test int "<<test_int->getValue();
    qtch::ConfigVar<int>::ptr test_xx = qtch::Config::LookUp("server.port",8080,"server port");
    QTCH_LOG_INFO(logger)<<"test xx "<<test_xx->getValue();
    QTCH_LOG_INFO(logger)<<"test xx to string "<<test_xx->toString();
    test_xx->fromString("100");
    QTCH_LOG_INFO(logger)<<"test xx after from string "<<test_xx->getValue();

}

void test_config_LexicalCast(){
    QTCH_LOG_INFO(logger)<<" begin test_config_LexicalCast";
    qtch::ConfigVar<std::vector<int> >::ptr test_int_vec = qtch::Config::LookUp("server.int_vec",std::vector<int>{1,2,3,4},"server int vector");
    QTCH_LOG_INFO(logger)<<std::endl<<" show int vector to string="<<test_int_vec->toString();
    test_int_vec->fromString("- 99\n- 98\n- 97\n- 96");
    QTCH_LOG_INFO(logger)<<std::endl<<" show int vector to string="<<test_int_vec->toString();

    qtch::ConfigVar<std::set<int> >::ptr test_int_set = qtch::Config::LookUp("server.int_set",std::set<int>{1,2,3,4,4},"server int set");
    QTCH_LOG_INFO(logger)<<std::endl<<" show int set to string="<<test_int_set->toString();
    test_int_set->fromString("- 99\n- 98\n- 97\n- 97\n- 96");
    QTCH_LOG_INFO(logger)<<std::endl<<" show int set to string="<<test_int_set->toString();

    qtch::ConfigVar<std::unordered_set<int> >::ptr test_int_unordered_set = qtch::Config::LookUp("server.int_unordered_set",std::unordered_set<int>{1,2,3,4,4},"server int unordered_set");
    QTCH_LOG_INFO(logger)<<std::endl<<" show int unordered_set to string="<<test_int_unordered_set->toString();
    test_int_unordered_set->fromString("- 99\n- 98\n- 97\n- 97\n- 96");
    QTCH_LOG_INFO(logger)<<std::endl<<" show int unordered_set to string="<<test_int_unordered_set->toString();

    qtch::ConfigVar<std::list<int> >::ptr test_int_list = qtch::Config::LookUp("server.int_list",std::list<int>{1,2,3,4},"server int list");
    QTCH_LOG_INFO(logger)<<std::endl<<" show int list to string="<<test_int_list->toString();
    test_int_list->fromString("- 99\n- 98\n- 97\n- 97\n- 96");
    QTCH_LOG_INFO(logger)<<std::endl<<" show int list to string="<<test_int_list->toString();

    qtch::ConfigVar<std::map<std::string, int> >::ptr test_int_map = qtch::Config::LookUp("server.int_map",std::map<std::string, int>{{"ss",1},{"aa",2}},"server int map");
    QTCH_LOG_INFO(logger)<<std::endl<<" show int map to string="<<test_int_map->toString();
    test_int_map->fromString("xx: 3\nyy: 4");
    QTCH_LOG_INFO(logger)<<std::endl<<" show int map to string="<<test_int_map->toString();

    qtch::ConfigVar<std::unordered_map<std::string, int> >::ptr test_int_unordered_map = qtch::Config::LookUp("server.int_unordered_map",std::unordered_map<std::string, int>{{"ss",1},{"aa",2}},"server int unordered_map");
    QTCH_LOG_INFO(logger)<<std::endl<<" show int unordered_map to string="<<test_int_unordered_map->toString();
    test_int_unordered_map->fromString("xx: 3\nyy: 4");
    QTCH_LOG_INFO(logger)<<std::endl<<" show int unordered_map to string="<<test_int_unordered_map->toString();


    QTCH_LOG_INFO(logger)<<" end test_config_LexicalCast";
}

void test_loadConfigFile(){
    qtch::ConfigVar<std::string>::ptr test = qtch::Config::LookUp("test",std::string("value1"),"test");
    qtch::ConfigVar<int>::ptr number = qtch::Config::LookUp("number",300,"number");
    qtch::ConfigVar<std::list<std::string> >::ptr seq = qtch::Config::LookUp("seq",std::list<std::string>{"test1","test2"},"seq");
    qtch::ConfigVar<std::string>::ptr node0 = qtch::Config::LookUp("node_2.0",std::string("node0"),"node0");
    qtch::ConfigVar<std::string>::ptr node1 = qtch::Config::LookUp("node_2.1",std::string("node1"),"node1");
    qtch::ConfigVar<std::string>::ptr node2 = qtch::Config::LookUp("node_2.2",std::string("node2"),"node2");
    qtch::ConfigVar<std::list<int> >::ptr node3 = qtch::Config::LookUp("node_2.3",std::list<int>{3,3,3,3,3,3},"node3");
    QTCH_LOG_INFO(logger)<<" show test="<<test->toString();
    QTCH_LOG_INFO(logger)<<" show number="<<number->toString();
    QTCH_LOG_INFO(logger)<<" show seq="<<seq->toString();
    QTCH_LOG_INFO(logger)<<" show node0="<<node0->toString();
    QTCH_LOG_INFO(logger)<<" show node1="<<node1->toString();
    QTCH_LOG_INFO(logger)<<" show node2="<<node2->toString();
    QTCH_LOG_INFO(logger)<<" show node3="<<node3->toString();
    //qtch::Config::LoadYamlFile("./bin/conf/test.yml");
    qtch::Config::LoadConfigDir("/home/qiu/qtch/bin/conf");
    QTCH_LOG_INFO(logger)<<" show test="<<test->toString();
    QTCH_LOG_INFO(logger)<<" show number="<<number->toString();
    QTCH_LOG_INFO(logger)<<" show seq="<<seq->toString();
    QTCH_LOG_INFO(logger)<<" show node0="<<node0->toString();
    QTCH_LOG_INFO(logger)<<" show node1="<<node1->toString();
    QTCH_LOG_INFO(logger)<<" show node2="<<node2->toString();
    QTCH_LOG_INFO(logger)<<" show node3="<<node3->toString();
}

void test_log_config(){
    QTCH_LOG_INFO(QTCH_LOG_ROOT()) << "log root config ";
    QTCH_LOG_INFO(QTCH_LOG_NAME("system")) << "log system config ";
    qtch::Config::LoadConfigDir("/home/qiu/qtch/bin/conf");
    QTCH_LOG_INFO(QTCH_LOG_ROOT()) << "log root config ";
    QTCH_LOG_INFO(QTCH_LOG_NAME("system")) << "log system config ";
}

int main(int argc, char **argv){
    //test_yaml();
    //test_config();
    //test_config_LexicalCast();
    //test_loadConfigFile();
    test_log_config();
}